package com.eastfair.venuebooking.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.annotation.annotation.dictionary.DictionaryField;
import com.eastfair.auth.vo.UserAccountVo;
import com.eastfair.boot.request.PageParams;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.projectcore.api.DictionaryFeign;
import com.eastfair.projectcore.entity.Dictionary;
import com.eastfair.util.DateTimeUtil;
import com.eastfair.venuebooking.dao.BusinessOpportunityMapper;
import com.eastfair.venuebooking.dto.BusinessOpportunityQuery;
import com.eastfair.venuebooking.dto.SalesAnalysisDTO;
import com.eastfair.venuebooking.entity.BusinessOpportunity;
import com.eastfair.venuebooking.entity.ContractManage;
import com.eastfair.venuebooking.entity.Space;
import com.eastfair.venuebooking.enums.VenueBookingMoudleEnum;
import com.eastfair.venuebooking.service.*;
import com.eastfair.venuebooking.vo.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sun.istack.NotNull;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 统计分析
 * </p>
 *
 * @author lyw
 * @date 2022-07-04
 */
@Slf4j
@Service
public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisService {

    @Autowired
    private BusinessOpportunityService businessOpportunityService;
    @Autowired
    private ContractManageService contractManageService;
    @Autowired
    private SpaceService spaceService;
    @Autowired
    private DictionaryFeign dictionaryFeign;
    @Autowired
    private QuotationDetailService quotationDetailService;

    /**
     * 销售分析
     *
     * @return
     */
    @Override
    public StatisticalAnalysisTotalVO getStatisticalAnalysisTotalData(SalesAnalysisDTO salesAnalysisDTO) {
        //根据1年,2月,3周,4日查询
        if (Objects.nonNull(salesAnalysisDTO) && Objects.nonNull(salesAnalysisDTO.getCalendar())) {
            switch (salesAnalysisDTO.getCalendar()) {
                case 1:
                    salesAnalysisDTO.setStartTime(DateTimeUtil.getOneDayOfYear());
                    salesAnalysisDTO.setEndTime(DateTimeUtil.getEndDayOfYear());
                    break;
                case 2:
                    salesAnalysisDTO.setStartTime(DateTimeUtil.getOneDayOfMonth());
                    salesAnalysisDTO.setEndTime(DateTimeUtil.getEndDayOfMonth());
                    break;
                case 3:
                    salesAnalysisDTO.setStartTime(DateTimeUtil.getStartWeek());
                    salesAnalysisDTO.setEndTime(DateTimeUtil.getEndWeek());
                    break;
                case 4:
                    salesAnalysisDTO.setStartTime(DateTimeUtil.getDayStartTime());
                    salesAnalysisDTO.setEndTime(DateTimeUtil.getDayEndTime());
                    break;

            }
        }
        StatisticalAnalysisTotalVO statisticalAnalysisTotalVO = new StatisticalAnalysisTotalVO();
        //获取商机销售阶段
        R<List<Dictionary>> listR = dictionaryFeign.queryDict(VenueBookingMoudleEnum.BUSINESS_STAGE.getCode());
        //获取商机总的数据
        List<BusinessOpportunity> businessOpportunityListTotal = businessOpportunityService.getBusinessOpportunityList(salesAnalysisDTO);
        //销售漏斗统计数据
        Map<String, String> map = Maps.newHashMap();
        //销售列表
        List<SalesAnalysisVO> salesAnalysisVOList = Lists.newArrayList();
        //预计销售金额
        BigDecimal amountTotal = new BigDecimal("0");
        //需求确定概率金额
        BigDecimal chanceAmountTotal = new BigDecimal("0");
        if (Objects.nonNull(listR) && Objects.nonNull(listR.getData()) && listR.getData().size() > 0) {
            for (Dictionary s : listR.getData()) {
                salesAnalysisDTO.setSalesStage(s.getCode());
                List<BusinessOpportunity> businessOpportunityList = businessOpportunityService.getBusinessOpportunityList(salesAnalysisDTO);
                SalesAnalysisVO salesAnalysisOneVO = new SalesAnalysisVO();
                //预计销售金额
                BigDecimal amount = new BigDecimal("0");
                //需求确定概率金额
                BigDecimal chanceAmount = new BigDecimal("0");
                if (Objects.nonNull(businessOpportunityList) && businessOpportunityList.size() > 0) {

                    for (BusinessOpportunity businessOpportunity : businessOpportunityList) {
                        amount = amount.add(businessOpportunity.getEstimateSalesAmount());
                        // BigDecimal chanceAmountOne = getChanceAmount(businessOpportunity);
                        //方案报价概率金额
                        // chanceAmount=chanceAmount.add(chanceAmountOne).setScale(2, RoundingMode.HALF_UP);

                    }

                    Double percentage = (double) businessOpportunityList.size() / businessOpportunityListTotal.size() * 100;
                    int nextIntValue = (int) Math.round(percentage);
                    map.put(s.getName() + businessOpportunityList.size(), nextIntValue + "%");
                    salesAnalysisOneVO.setSalesStageName(s.getName());
                    salesAnalysisOneVO.setSalesStage(s.getCode());
                    salesAnalysisOneVO.setBusinessSum(businessOpportunityList.size());
                    salesAnalysisOneVO.setConversionRate(nextIntValue);
                    salesAnalysisOneVO.setEstimateSalesAmount(amount);
                    // salesAnalysisOneVO.setChanceAmount(chanceAmount);
                    salesAnalysisVOList.add(salesAnalysisOneVO);

                }


            }

            //数据汇总
            statisticalAnalysisTotalVO.setMap(map);
            statisticalAnalysisTotalVO.setSalesAnalysisVOList(salesAnalysisVOList);

        }
        return statisticalAnalysisTotalVO;
    }


    /**
     * 场地出租率统计数据
     *
     * @return
     */
    @Override
    public SpaceLeaseStatisticsTotalVO getSpaceLeaseStatisticsTotalData(SalesAnalysisDTO salesAnalysisDTO) {
        SpaceLeaseStatisticsTotalVO spaceLeaseStatisticsTotalVO =new SpaceLeaseStatisticsTotalVO();
        List<Integer> countList=Lists.newArrayList();
        List<SpaceLeaseStatisticsVO> spaceLeaseStatisticsVOList=Lists.newArrayList();

        for(int i=1;i<=12;i++){
            Map<String, LocalDateTime> monthTime = getFirstDayAndLastDayOfTheSpecifiedMonth(salesAnalysisDTO.getYear(), i);
            salesAnalysisDTO.setStartTime(monthTime.get("start"));
            salesAnalysisDTO.setEndTime(monthTime.get("end"));
            Integer monthSpaceLeaseStatistics= quotationDetailService.getSpaceLeaseStatisticsTotalData(salesAnalysisDTO);
            int monthSum = getMonthSum(salesAnalysisDTO.getYear(), i);
            List<Space> spaceList = spaceService.getSpaceList(salesAnalysisDTO);
            if(Objects.nonNull(spaceList)&& spaceList.size()>0){
                for(Space space:spaceList){
                    SpaceLeaseStatisticsVO spaceLeaseStatisticsVO =new SpaceLeaseStatisticsVO();
                    salesAnalysisDTO.setSpaceId(space.getId());
                    Integer monthStatistics= quotationDetailService.getSpaceLeaseStatisticsTotalData(salesAnalysisDTO);
                    BigDecimal bigDecimalMonthStatistics = new BigDecimal(monthStatistics);
                    Integer sum = space.getPriceArea().intValue() * monthSum;
                    BigDecimal bigDecimalSum = new BigDecimal(sum);
                    //月可供
                    spaceLeaseStatisticsVO.setMonthlyRentalArea(sum.toString());
                    //实际可供
                    spaceLeaseStatisticsVO.setActualRentalArea(monthStatistics.toString());
                    //月出租率
                    if(bigDecimalMonthStatistics.compareTo(BigDecimal.ZERO)==0){
                        spaceLeaseStatisticsVO.setRate("0");
                    }else {
                        BigDecimal divide = bigDecimalSum.divide(bigDecimalMonthStatistics,BigDecimal.ROUND_CEILING);
                        spaceLeaseStatisticsVO.setRate(divide.toString());
                    }
                    spaceLeaseStatisticsVO.setDate(salesAnalysisDTO.getYear()+"-"+i);
                    spaceLeaseStatisticsVOList.add(spaceLeaseStatisticsVO);
                }
            }
            countList.add(monthSpaceLeaseStatistics);
        }
        spaceLeaseStatisticsTotalVO.setMonthSpaceLeaseStatisticsList(countList);
        spaceLeaseStatisticsTotalVO.setSpaceLeaseStatisticsVOList(spaceLeaseStatisticsVOList);
        return spaceLeaseStatisticsTotalVO;
    }

    /**
     * 场地出租面积
     * @param salesAnalysisDTO
     * @return
     */
    @Override
    public SpaceLeaseStatisticsTotalVO getSpaceLeaseStatisticsTotalArea(SalesAnalysisDTO salesAnalysisDTO) {
        SpaceLeaseStatisticsTotalVO spaceLeaseStatisticsTotalVO =new SpaceLeaseStatisticsTotalVO();
        List<String> monthSpaceAreaSumList=Lists.newArrayList();
        List<Space> spaceList = spaceService.getSpaceList(salesAnalysisDTO);
        Map<String, LocalDateTime> monthTime = getFirstDayAndLastDayOfTheSpecifiedMonth(salesAnalysisDTO.getYear(), salesAnalysisDTO.getMonth());
        salesAnalysisDTO.setStartTime(monthTime.get("start"));
        salesAnalysisDTO.setEndTime(monthTime.get("end"));
        if(Objects.nonNull(spaceList)&& spaceList.size()>0) {
            for (Space space : spaceList) {
                salesAnalysisDTO.setSpaceId(space.getId());
                Integer monthSpaceLeaseStatistics= quotationDetailService.getSpaceLeaseStatisticsTotalData(salesAnalysisDTO);
                monthSpaceAreaSumList.add(monthSpaceLeaseStatistics.toString());
            }
        }
        spaceLeaseStatisticsTotalVO.setSpaceList(spaceList);
        spaceLeaseStatisticsTotalVO.setMonthSpaceAreaSumList(monthSpaceAreaSumList);
        return spaceLeaseStatisticsTotalVO;
    }


    /**
     * 获取某个销售阶段数据集合
     *
     * @param pageParams
     * @return
     */
    @Override
    public IPage<BusinessOpportunityVO> getStatisticalAnalysisByCode(PageParams<SalesAnalysisDTO> pageParams) {
        //获取商机销售阶段
        R<List<Dictionary>> listR = dictionaryFeign.queryDict(VenueBookingMoudleEnum.BUSINESS_STAGE.getCode());
        IPage<BusinessOpportunityVO> pageList = businessOpportunityService.getBusinessOpportunityPageList(pageParams);
        //获取商机销售阶段名称
        Map<String, Dictionary> map = listR.getData().stream().collect(Collectors.toMap(Dictionary::getCode, Function.identity()));
        pageList.getRecords().forEach((s) -> {
            s.setSalesStageName(map.get(s.getSalesStage()).getName());
        });
        return pageList;
    }

    /**
     * 获取概率总金额
     *
     * @param businessOpportunity
     * @return
     */
    private BigDecimal getChanceAmount(BusinessOpportunity businessOpportunity) {
        //成交率
        BigDecimal dealProbability = BigDecimal.valueOf(Double.valueOf(businessOpportunity.getDealProbability().substring(0, businessOpportunity.getDealProbability().length() - 1)));
        BigDecimal divide = dealProbability.divide(new BigDecimal("100"));
        BigDecimal multiply = businessOpportunity.getEstimateSalesAmount().multiply(divide).setScale(2, RoundingMode.HALF_UP);
        return multiply;
    }



    // 获取指定年指定月的开始天数和结束天数
    public static Map<String,LocalDateTime> getFirstDayAndLastDayOfTheSpecifiedMonth(int year, int month) {
        // 获取当前分区的日历信息(这里可以使用参数指定时区)
        Calendar calendar = Calendar.getInstance();
        // 设置年
        calendar.set(Calendar.YEAR, year);
        // 设置月，月份从0开始
        calendar.set(Calendar.MONTH, month - 1);
        // 设置为指定月的第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        // 获取指定月第一天的时间
        LocalDateTime start = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        // 设置日历天数为当前月实际天数的最大值，即指定月份的最后一天
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        // 获取最后一天的时间
        LocalDateTime end = calendar.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        // 设置返回信息,返回样式根据需求自行格式化
        Map<String,LocalDateTime> dateMap = new HashMap<>();
        dateMap.put("start",start);
        dateMap.put("end",end);
        return dateMap;
    }

    /**
     * 获取月天数
     * @return
     */
    private int getMonthSum(int year,int month){
        int day =0;
        switch (month){
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                day =31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                day =30;
                break;
            case 2:
                if((year%4==0)&&(year%100!=0)||(year%400==0)){
                    day=29;
                }
                else{
                    day=28;
                }
                break;
        }

        return day;
    }

    public static void main(String[] args) {
        for(int i=1;i<=12;i++){
            System.out.println(i);
        }
    }

}